 
 
 module dynamic_seg_led (
    input sys_clk,
    input sys_rst,
    
    input [19:0] data,
    input [5:0]  points,
    input en,
    
    output reg [5:0] seg_sel,
    output reg [7:0] seg_led
 ); 
 
 localparam SEG_DRIVE_PERIOD = 13'd50000000;
 
reg [23:0]  seg_led_BCD_digits;             //8421数字
reg seg_sel_drive_switch_flag;              //数码管段选择切换标记
reg [12:0] seg_sel_drive_switch_timer;      //数码管段选择周期计数器
reg [2:0]  seg_sel_num;                       //当前显示段号
reg [3:0]  seg_led_disp_num;                //当前数码管显示柱子
reg        dot_display;

//wire define 
wire [3:0]  data0;
wire [3:0]  data1;
wire [3:0]  data2;
wire [3:0]  data3;
wire [3:0]  data4;
wire [3:0]  data5;    

//提取显示数值所对应的十进制数的各个位
assign data0 = data % 4'd10;                        //个位数
assign data1 = (data / 4'd10) % 4'd10;              //10位数
assign data2 = (data / 7'd100) % 7'd100;            //百位
assign data3 = (data / 10'd1000) % 10'd1000;        //千位
assign data4 = (data / 14'd10000) % 14'd10000;      //万位
assign data5 = (data / 17'd100000) % 17'd100000;    //十万位

always @(posedge sys_clk or negedge sys_rst) begin

     if (!sys_rst) begin
        seg_led_BCD_digits <= 24'h000000;
     end
     else begin
        seg_led_BCD_digits[3:0] <= data0;
        seg_led_BCD_digits[7:4] <= data1;
        seg_led_BCD_digits[11:8] <= data2;
        seg_led_BCD_digits[15:12] <= data3;
        seg_led_BCD_digits[19:16] <= data4;
        seg_led_BCD_digits[23:20] <= data5;
     
     end

end

 //数字管驱动定时器周期为1ms,输出一个周期为1ms的周期信号
 always @(posedge sys_clk or negedge sys_rst) begin
    if (!sys_rst) begin 
        seg_sel_drive_switch_timer <= 13'd0;
        seg_sel_drive_switch_flag = 1'b0;
    end
    else if (seg_sel_drive_switch_timer < SEG_DRIVE_PERIOD) begin
        seg_sel_drive_switch_timer <= seg_sel_drive_switch_timer + 1'b1;
        seg_sel_drive_switch_flag <= 1'b0;
    end
    else begin
        seg_sel_drive_switch_flag = 1'b1;
        seg_sel_drive_switch_timer <= 13'd0;
    end
 end
 

 
 //控制数码管段选信号，使数码管轮流显示
 always @(posedge sys_clk or negedge sys_rst) begin
    if (!sys_rst) begin 
        seg_sel_num <= 3'd0;                            
    end
    else if (seg_sel_drive_switch_flag == 1'b1) begin
        if (seg_sel_num < 3'd5)
            seg_sel_num <= seg_sel_num + 1'b1;
        else
            seg_sel_num <= 3'd0;
    end
 
 end
 
 
 //控制数码管位选信号，使数码管显示数字
 always @(posedge sys_clk or negedge sys_rst) begin

    if (!sys_rst) begin
        seg_sel <= 6'b111111;                   //默认数码管全灭
    end
    else  begin
        if (en == 1'b1) begin
            case (seg_sel_num)
                3'd0 : begin
                    seg_sel <= 6'b111110;       //显示数码管位(第1位)
                    dot_display <= ~points[0];
                    seg_led_disp_num <= seg_led_BCD_digits[3:0];
                end
                3'd1 : begin
                    seg_sel <= 6'b111101;       //显示数码管位(第2位)
                    seg_led_disp_num <= seg_led_BCD_digits[7:4];
                    dot_display <= ~points[1];
                end
                3'd2 : begin
                    seg_sel <= 6'b111011;       //显示数码管位(第3位)
                    seg_led_disp_num <= seg_led_BCD_digits[11:8];
                    dot_display <= ~points[2];
                end
                3'd3 : begin
                    seg_sel <= 6'b110111;       //显示数码管位(第4位)
                    seg_led_disp_num <= seg_led_BCD_digits[15:12];
                    dot_display <= ~points[3];
                end
                3'd4 : begin
                    seg_sel <= 6'b101111;       //显示数码管位(第5位)
                    seg_led_disp_num <= seg_led_BCD_digits[19:16];
                    dot_display <= ~points[4];
                end
                3'd5 : begin
                    seg_sel <= 6'b011111;       //显示数码管位(第6位)
                    seg_led_disp_num <= seg_led_BCD_digits[23:20];
                    dot_display <= ~points[5];
                end
                default: begin
                    seg_sel <= 6'b111111;
                    seg_led_disp_num <= 4'b0;
                    dot_display <= 1'b1;
                end
            endcase
        end
    end
 end
 
 //控制数码管段选信号，显示字符
always @ (posedge sys_clk or negedge sys_rst) begin
    if (!sys_rst)
        seg_led <= 8'hc0;
    else begin
        case (seg_led_disp_num)
            4'd0 : seg_led <= {dot_display,7'b1000000}; //显示数字 0
            4'd1 : seg_led <= {dot_display,7'b1111001}; //显示数字 1
            4'd2 : seg_led <= {dot_display,7'b0100100}; //显示数字 2
            4'd3 : seg_led <= {dot_display,7'b0110000}; //显示数字 3
            4'd4 : seg_led <= {dot_display,7'b0011001}; //显示数字 4
            4'd5 : seg_led <= {dot_display,7'b0010010}; //显示数字 5
            4'd6 : seg_led <= {dot_display,7'b0000010}; //显示数字 6
            4'd7 : seg_led <= {dot_display,7'b1111000}; //显示数字 7
            4'd8 : seg_led <= {dot_display,7'b0000000}; //显示数字 8
            4'd9 : seg_led <= {dot_display,7'b0010000}; //显示数字 9
            4'd10: seg_led <= 8'b11111111;           //不显示任何字符
            4'd11: seg_led <= 8'b10111111;           //显示负号(-)
            default: 
                   seg_led <= {dot_display,7'b1000000};
        endcase
    end
end
 
 endmodule